home *** CD-ROM | disk | FTP | other *** search
- {
- ╔═════════════════════════════════════════════════════════════════════════════╗
- ║ NAME : MODEM.PAS ║
- ║ FUNCTION : Library to control the used (TeleTex OR HAYES) modem. ║
- ║ REMARKS : ■ To activate this unit clock interrupt, you have to include the║
- ║ : following lines in the main routine: ║
- ║ : GetIntVec($1C,Int1CSave); ║
- ║ : SetIntVec($1C,Addr(Check_HModem_State)); ║
- ║ : Do NOT forget to disactivate it before terminating the program: ║
- ║ : SetIntVec($1C,Int1CSave); ║
- ║ : This interrupt will up-date the "connected" variable at each ║
- ║ : second for an HAYES modem. It will also up-date the "C" signal ║
- ║ : into screen to inform the user that he is connected ("ShowCorF" ║
- ║ : has to be set TRUE for this...). ║
- ║ : Please, note that "HayesModemState" and "Check_HModem_State" ║
- ║ : can't be used to check the connect status of the Minitel: ║
- ║ : The connect status of it must be interpreted by the VideoTex ║
- ║ : transcoding procedure... ║
- ║ COPYRIGHT : HETRU Fabrice 1991-1995. ║
- ╚═════════════════════════════════════════════════════════════════════════════╝
- }
-
-
-
- UNIT Modem;
-
-
-
- interface
-
- USES Crt,Dos,StarIntf;
-
- TYPE
- CmdeStr = STRING[20] ;
-
- CONST
- (* Modem type in use: MINITEL ou HAYES ? *)
- TlTex = 0 ;
- Hayes = 1 ;
- (* Command codes to send to the modem. *)
- Generique = 0 ;
- InitMod = 1 ;
- Connect = 2 ;
- Appel = 3 ;
- Raccroch = 4 ;
- ConnexFin = 5 ;
- (* Screen RAM Segment. *)
- seg_ecran : WORD = $B000 ;
-
- VAR
- ModemUsed : SHORTINT ; (* Modem type in use: Hayes/Minitel ? *)
- DTR_Cmde : BOOLEAN ; (* Is DTR used as a command prefix ? *)
- HAYESPrefix : STRING[3] ; (* Command prefix for the HAYES modem. *)
- PulseDial : BOOLEAN ; (* Pulses call ? (or Frequency calls ?). *)
- connected : BOOLEAN ; (* Connected status flag. *)
- Show_CorF : BOOLEAN ; (* Write (or not) the connect status on screen*)
- Int1CSave : POINTER ; (* Back-up for the last interrupt vector... *)
-
- PROCEDURE CmdeToModem(TypCmde: BYTE;DataCmde: CmdeStr);
- { HAYES and TlTex commands maker. }
- PROCEDURE HayesModemState; { Up-dates the connect status. }
- PROCEDURE Check_HModem_State; INTERRUPT; { Clock interrupt to check the con- }
- { -nect status... }
-
-
-
- implementation
-
- TYPE
- Vecteur = RECORD
- Offset : WORD ;
- Segment : WORD ;
- END;
-
-
- CONST
- OldIntrp1C : Vecteur = (Offset:0;Segment:0) ;
-
-
- VAR
- reg88 : Registers ;
- ItClk_active : BOOLEAN ;
-
-
- PROCEDURE Beep(Freq, Tempo: WORD);
- BEGIN
- Sound(Freq);
- Delay(Tempo);
- NoSound
- END;
-
-
- PROCEDURE CmdeToModem(TypCmde: BYTE;DataCmde: CmdeStr);
- VAR
- Chaine_CMDE : CmdeStr ;
- Sended,
- Nb_transmited : WORD ;
- BEGIN
- Chaine_CMDE := '';
- CASE ModemUsed OF
- TlTex: BEGIN
- CASE TypCmde OF
- Generique: Chaine_CMDE := #$1B+#$39+#$67;
- InitMod: Chaine_CMDE := '';
- Connect: Chaine_CMDE := #$1B+#$39+#$68;
- Appel: Chaine_CMDE := '';
- Raccroch: Chaine_CMDE := #$1B+#$39+#$67;
- ConnexFin: IF connected THEN Chaine_CMDE := #$13+#$49
- ELSE Chaine_CMDE := #$1B+#$39+#$68
- END;
- IF Length(Chaine_CMDE)>0 THEN
- IF WriteSerie(Chaine_CMDE[1],Length(Chaine_CMDE),Nb_transmited)<>0
- THEN Beep(500,500)
- END;
- Hayes: BEGIN
- CASE TypCmde OF
- Generique: Chaine_CMDE := Chaine_CMDE + DataCmde;
- InitMod:
- IF DTR_Cmde THEN Chaine_CMDE := 'AT Z0 &D1 X0 V2 B2'
- ELSE Chaine_CMDE := Chaine_CMDE + 'AT Z0 X0 V2 B2';
- Connect: Chaine_CMDE := Chaine_CMDE + 'ATD';
- Appel: IF connected OR (DataCmde='') THEN Chaine_CMDE := ''
- ELSE
- BEGIN
- Chaine_CMDE := Chaine_CMDE + 'ATD' ;
- IF PulseDIAL THEN Chaine_CMDE := Chaine_CMDE + 'P'
- ELSE Chaine_CMDE := Chaine_CMDE + 'T';
- Chaine_CMDE := Chaine_CMDE + DataCmde
- END;
- Raccroch: Chaine_CMDE := Chaine_CMDE + 'ATH0';
- ConnexFin: IF connected THEN Chaine_CMDE := Chaine_CMDE + 'ATH0'
- ELSE Chaine_CMDE := Chaine_CMDE + 'ATD'
- END;
- IF Length(Chaine_CMDE)>0 THEN
- BEGIN
- IF NOT DTR_Cmde THEN
- BEGIN
- IF connected THEN
- BEGIN
- Delay(1000);
- Sended:=WriteCmde(HAYESPrefix[1],Length(HAYESPrefix),DTR_Cmde);
- IF Sended=0 THEN Delay(1000);
- END
- ELSE Sended := 0;
- END
- ELSE Sended := 0;
- IF Sended=0 THEN
- BEGIN
- Chaine_CMDE := Chaine_CMDE + #$0D;
- IF WriteCmde(Chaine_CMDE[1],Length(Chaine_CMDE),DTR_Cmde)<>0
- THEN Beep(500,500);
- IF connected THEN
- BEGIN
- Delay(1200);
- Chaine_Cmde := 'ATO' + #$0D;
- Sended:=WriteCmde(Chaine_CMDE[1],Length(Chaine_CMDE),FALSE);
- END
- END;
- END
- END;
- END
- END;
-
-
- PROCEDURE HayesModemState;
- VAR
- voie : CHAR ;
- x : BOOLEAN ;
- xx : BYTE ;
- BEGIN
- IF ModemUsed=Hayes THEN
- Etat_du_modem(voie,x,x,x,connected,x,xx,xx,xx,xx)
- END;
-
-
- {$F+}
- PROCEDURE Check_HModem_State;
- VAR
- compteur : BYTE ;
- BEGIN
- (* Up-date at each second... *)
- Inc(compteur);
- IF (compteur>=$12) AND NOT ItClk_active THEN
- BEGIN
- (* No multiple entrance in this area ! *)
- ItClk_active := TRUE;
-
- (* 8259 and CPU acquittance to allow the serial receipts... *)
- Inline($50/ (* push ax *)
- $B0/$20/ (* mov al,20h *)
- $E6/$20/ (* out 20h,al *)
- $58); (* pop ax *)
- Inline($FB); (* sti *)
-
- (* Checking the connect status. *)
- HayesModemState;
-
- (* Writting the "C" or "F" alert into screen. *)
- IF Show_CorF THEN
- BEGIN
- IF connected THEN
- BEGIN
- IF MEM[$40:$49] IN [2,3,7] THEN
- MEMW[seg_ecran:158] := $7043
- ELSE MEMW[seg_ecran:76] := $7043
- END
- ELSE
- BEGIN
- IF MEM[$40:$49] IN [2,3,7] THEN
- MEMW[seg_ecran:158] := $7046
- ELSE MEMW[seg_ecran:76] := $7046
- END;
- END;
-
- (* That's the end of our clock interrupt. *)
- ItClk_active := FALSE;
- compteur := 0
- END;
-
- (* Call to the previous clock interrupt *)
- Inline($9C/ (* pushf *)
- $FF/$1E/OldIntrp1C) (* call far dword ptr ds:OldIntrp1C *)
- END;
- {$F-}
-
-
- BEGIN
- ModemUsed := Hayes; (* HAYES Modem in use... *)
- DTR_Cmde := TRUE; (* We want to use DTR as a Cmde indicator*)
- HAYESPrefix := '+++'; (* That's the default HAYES Cmde prefix. *)
- PulseDial := TRUE; (* Pulses call in use. *)
- connected := FALSE; (* We are supposed not to be connected ! *)
- Show_CorF := FALSE; (* No connection flag on screen. *)
- ItClk_active := FALSE; (* Clock interrupt is NOT activated yet. *)
- IF MEM[$0040:$0049]=7 THEN (* Video RAM segment. *)
- seg_ecran := $B000
- ELSE seg_ecran := $B800;
- WITH reg88 DO
- BEGIN (* Stores the previous clock interrupt *)
- ax := $351C; (* in use before setting the new one. *)
- Intr($21,Dos.Registers(reg88));
- OldIntrp1C.Offset := bx;
- OldIntrp1C.Segment := es;
- END;
- NoSound (* Speaker initialization... *)
- END.